<template>
  <a-card
    class="general-card"
    title="角色管理"
    :bordered="false"
  >
    <a-row style="margin-bottom: 16px">
      <a-col :span="16">
        <a-space>
          <a-button type="primary" @click="handleAdd">
            添加
          </a-button>
          <!-- <a-button @click="delAll"> 批量删除 </a-button> -->
        </a-space>
      </a-col>
    </a-row>
    <PickTablePage
      ref="tablePageRef"
      :columns="columnsTable"
      :methods="sortMethods"
      :api="getRoleList"
      :checkbox="true"
      @delete="handleDelete"
      @editor="handleEdit"
      @editPerm="handleEditPerm"
      @selectTableChange="selectTableChange"
    >
      <template #btnList="{ data }">
        <a-space size="large">
          <a-switch
            v-model="data.disabled"
            checked-value="OPEN"
            unchecked-value="CLOSE"
          >
            <template #checked> 启用 </template>
            <template #unchecked> 禁用 </template>
          </a-switch>
        </a-space>
      </template>
    </PickTablePage>
    <!-- 添加/编辑modal -->
    <a-modal
      v-model:visible="roleData.enableAddModal"
      :align-center="false"
      :footer="false"
      :maskClosable="false"
    >
      <template #title> {{ title }} </template>
      <a-form ref="formRef" :model="roleData.form" @submit="handleAddOk">
        <a-form-item
          field="name"
          label="角色名称"
          :rules="[REQUIRED, VARCHAR20]"
          :validate-trigger="['change']"
        >
          <a-input v-model="roleData.form.name" />
        </a-form-item>
        <a-form-item field="code" label="备注" :validate-trigger="['change']">
          <a-input v-model="roleData.form.description" />
        </a-form-item>
        <a-form-item label="操作">
          <a-button :loading="roleData.formLoading" html-type="submit"
          type="primary"  >保存</a-button
          >
        </a-form-item>
      </a-form>
    </a-modal>
    <a-modal
      v-model:visible="permModalVisible"
      :align-center="false"
      @cancel="permModalVisible = false"
      @ok="submitPermEdit"
    >
      <template #title>
        {{ title }}
      </template>
      <div>
        <a-tree
          :data="permData"
          ref="treeRef"
          :checkable="true"
          :multiple="true"         
          v-model:checked-keys="rolePermsWay"
          :field-names="{ children: 'children', title: 'title', key: 'id' }"
          :only-check-leaf="true"
        >
          <template #extra="nodeData">
            <a-tag color="arcoblue" style="margin-left: 10px;" v-if="nodeData.isSuper == 1">操作权限</a-tag>
            <a-tag color="green" style="margin-left: 10px;" v-if="nodeData.isSuper == 0">查看权限</a-tag>
          </template>
        </a-tree>
      </div>
    </a-modal>
    <a-modal
      v-model:visible="selectIsSuperModel"
      :align-center="false"
      title="选择菜单权限"
      @ok="saveRole"
      :width="800"
    >
      <div class="btns">
        <a-button class="btn-item" type="outline" @click="setRole"
          >一键选中·数据权限</a-button
        >
        <a-button class="btn-item" type="outline" @click="setRole('onlyView')"
          >一键选中·查看权限</a-button
        >
      </div>
      <div class="role-list">
        <div
          class="role-item"
          v-for="(item, index) in saveRoleWay"
          :key="index"
        >
          <div class="title">{{ item.title }}</div>
          <div class="content">
            <a-radio-group type="button" @change="changeIsSuper($event,item)" v-model="item.isSuper">
              <a-radio :value="1">操作数据权限</a-radio>
              <a-radio :value="0">查看权限</a-radio>
            </a-radio-group>
          </div>
        </div>
      </div>
    </a-modal>
  </a-card>
</template>

<script setup lang="ts">
  import {
addRole,
deleteRole,
editRole,
getAllPermissionList,
getRoleList,
saveRoleMenu,
selectRoleMenu,
} from '@/api/setting';
import { PickTablePage } from '@pickmall/ui-v3-components'
import useCurrentInstance from '@/hooks/useCurrentInstance';
import { ColumnsDataRule, MethodsRule } from '@/types/global';
import { REQUIRED, VARCHAR20 } from '@/utils/validator';
import { Message } from '@arco-design/web-vue';
import { FormInstance } from '@arco-design/web-vue/es/form';
import { onMounted, reactive, ref } from 'vue';

  const tablePageRef = ref<any>();
  const title = ref<string>('');
  const selectList = ref([]); // 接收子组件传过来的值
  const formRef = ref<FormInstance>();
  const ids = ref<string>(''); // 多选行id
  const permModalVisible = ref(false); // 菜单权限modal
  const selectIsSuperModel = ref(false); // 保存权限弹出选择权限
  const permData = ref([]); // 菜单权限数据
  const saveRoleWay = ref<Array<any>>([]); // 用户保存用户点击的菜单
  const editRolePermId = ref(''); // 编辑权限id
  const rolePermsWay = ref([]); // 查询角色权限集合
  const treeRef = ref();
  interface formInterface {
    enableAddModal: boolean;
    formLoading: boolean;
    fid: string | number;
    form: {
      name: string;
      description: string;
      [key: string]: any;
    };
    [key: string]: any;
  }
  // 获取modal
  const modal = useCurrentInstance().globalProperties?.$modal;
  const columnsTable: ColumnsDataRule[] = [
    {
      title: '角色名称',
      dataIndex: 'name',
      width: 200,
    },
    {          
      title: '备注',
      dataIndex: 'description',
      width:200,
    },
    {
      title: '创建时间',
      dataIndex: 'createTime',
      width: 300,
    },
    {
      title: '更新时间',
      dataIndex: 'updateTime',
      width: 300,
    },
    {
      title: '最后操作人',
      dataIndex: 'createBy',
      width: 300,
    },
  ];

  const sortMethods: MethodsRule = {
    title: '操作',
    width: 300,
    fixed: 'right',
    methods: [
      {
        title: '菜单权限',
        callback: 'editPerm',
        type:'text'
      },
      {
        title: '编辑',
        callback: 'editor',
        type:'text',
        status:'warning'
      },
      {
        title: '删除',
        callback: 'delete',
        type:'text',
        status:'danger'
      },
    ],
  };
  const changeIsSuper = (val:any,item:any) =>{
   if(item.level === 0){
    // 选中一级之后为子集全选相同全选
    const current:any = permData.value.find((per: any) => item.menuId === per.id);
    const currentChildren = current.children
    if(currentChildren.length){
      // 遍历出所有子集
      const ids = currentChildren.map((per: any) => per.id)
      saveRoleWay.value.map((per: any) => {
        if(ids.includes(per.menuId)){
          per.isSuper = val
          
        }
      })
      Message.success(`已将${item.title}下所有子集权限设置为${val ? '操作' : '查看'}权限`)
    }
    }
  }
  // 数据集
  const roleData = reactive<formInterface>({
    enableAddModal: false,
    formLoading: false,
    fid: '', // 当前form的ids
    form: {
      name: '',
      description: '',
    }, // 表单提交数据
  });
  // 选择的行
  const selectTableChange = (val: any) => {
    selectList.value = val;
  };
  // 点击添加
  function handleAdd() {
    roleData.enableAddModal = true;
    title.value = '添加';
    roleData.fid = '';
    Object.keys(roleData.form).forEach((key) => {
      roleData.form[key] = '';
    });
  }
  // 添加/修改
  async function handleAddOk() {
    // roleData.form.password = this.md5(roleData.form.password);
    const auth = await formRef.value?.validate();
    if (!auth) {
      let res;
      !roleData.fid
        ? (res = await addRole(roleData.form))
        : (res = await editRole(roleData.fid, roleData.form));

      if (res.data.success) {
        Message.success(`${roleData.fid ? '修改' : '添加'}成功!`);
        roleData.enableAddModal = false;
        tablePageRef.value.init();
      }
    }
  }
  // 点击修改地址
  function handleEdit(val: any) {
    title.value = '编辑';
    if (val) {
      Object.keys(val.record).forEach((key) => {
        // eslint-disable-next-line no-unused-expressions,no-prototype-builtins
        roleData.form.hasOwnProperty(key)
          ? (roleData.form[key] = val.record[key])
          : '';
      });
      roleData.fid = val.record.id;
      roleData.enableAddModal = true;
    }
  }
  // 回调删除
  function handleDelete(data: any) {
    modal.confirm({
      title: '确认删除',
      content: `您确认要删除么?`,
      alignCenter: false,
      onOk: async () => {
        const res = await deleteRole(data.record.id);
        if (res.data.success) {
          Message.success('删除成功');
          tablePageRef.value.init();
        }
      },
    });
  }
  // 批量删除
  const delAll = () => {
    if (selectList.value.length <= 0) {
      Message.error('您还未选择要删除的数据');
      return;
    }
    selectList.value.forEach((item: any) => {
      ids.value += `${item.id},`;
    });
    const joinid = ids.value.substring(0, ids.value.length - 1);
    modal.confirm({
      title: '确认删除',
      content: `您确认要删除所选的${selectList.value.length}条数据?`,
      alignCenter: false,
      onOk: async () => {
        const res = await deleteRole(joinid);
        if (res.data.success) {
          Message.success('删除成功');
          tablePageRef.value.init();
        }
      },
    });
  };
  // 判断角色拥有的权限节点勾选
  const hasPerm = (p: any, rolePerms: any) => {
    if (!rolePerms) return false;
    let flag = false;
    for (let i = 0; i < rolePerms.length; i += 1) {
      if (p.id == rolePerms[i].menuId) {
        p.isSuper = rolePerms[i].isSuper;
        flag = true;
        break;
      }
    }
    if (flag) {
      return true;
    }
    return false;
  };
  // 递归判断子节段
  const checkPermTree = (permData: any, rolePerms: any) => {
    permData.forEach((p: any) => {
      if (hasPerm(p, rolePerms) && p.status != -1) {
        if (p.children && p.children.length === 0) {
          p.checked = true;
        }
      } else {
        p.checked = false;
      }
      if (p.children && p.children.length > 0) {
        checkPermTree(p.children, rolePerms);
      }
    });
  };
  // 菜单权限
  const handleEditPerm = async (val: any) => {
    // 点击菜单权限每次将赋值的isSuper数据给清空掉
    permData.value.forEach((item: any) => {
      if (item.children.length != 0) {
        item.children.forEach((child: any) => {
          if (child.children.length != 0) {
            child.children.forEach((kid: any) => {
              kid.key = kid.id
              delete kid.isSuper;
            });
          }
          delete child.isSuper;
        });
      }
      delete item.isSuper;
    });
    title.value = `分配${val.record.name}的菜单权限`;
    editRolePermId.value = val.record.id;
    // 匹配勾选
    let rolePerms = [];
    // 当前角色的菜单权限
    const res = await selectRoleMenu(val.record.id);
    if (res.data.result) {
      rolePerms = res.data.result;
      rolePermsWay.value = res.data.result.map((item: any)=>{
        return item.menuId
      })
    }
    // 递归判断子节点是否可以选中
    checkPermTree(permData.value, rolePerms);
    permModalVisible.value = true;
  };

  // 分配菜单权限
  const submitPermEdit = () => {
    saveRoleWay.value = [];
    selectIsSuperModel.value = true; // 打开选择权限
    const selectedNodes = treeRef.value.getCheckedNodes();
    const way = [] as any;
    selectedNodes.forEach((e: any) => {
      const perm = {
        title: e.title,
        isSuper: e.isSuper ? (e.isSuper = 1) : (e.isSuper = 0),
        menuId: e.id,
        roleId: editRolePermId.value,
        level:e.level
      };
      way.push(perm);
      saveRoleWay.value = way;
    });
  };
  // 查询菜单
  const getPermList = () => {
    getAllPermissionList().then((res) => {
      if (res.data.success) {
        permData.value = res.data.result.map((item: any) => {
          delete item.icon;
          return item;
        });
      }
    });
  };
  // 设置权限
  const setRole = (val: any) => {
    let enble = 0;
    if (val === 'onlyView') {
      enble = 0;
    } else {
      enble = 1;
    }
    saveRoleWay.value.forEach((item) => {
      item.isSuper = enble;
    });
  };

  // 保存权限
  const saveRole = () => {
    saveRoleMenu(editRolePermId.value, saveRoleWay.value).then((res) => {
      if (res.data.success) {
        Message.success('操作成功');
        tablePageRef.value.init();
        permModalVisible.value = false;
      }
    });
  };
  onMounted(() => {
    // 获取所有菜单权限树
    getPermList();
  });
</script>
<style lang="less" scoped>
  .role-list {
    height: 500px;
    overflow-y: auto;
    display: flex;
    flex-wrap: wrap;
  }
  .role-item {
    width: 50%;
    display: flex;
    padding: 20px 0;
    align-items: center;
    > .title {
      flex: 2;
      text-align: right;
    }
    > .content {
      flex: 10;
    }
  }

  .btns {
    display: flex;
    align-items: center;
    justify-content: center;
  }
  .btn-item {
    margin-right: 20px;
  }
  .title {
    font-weight: bold;
    margin-right: 20px;
  }
</style>
